package com.penghk.earth.util;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;

public class EncryptUtil {

    private static final String KEY_ALGORITHM1 = "DES";
    private static final String KEY_AES = "AES";

    //对称
    public static void DesTest(){
        try {
            BASE64Encoder encoder = new BASE64Encoder();

            // 1 : 生成秘钥
            KeyGenerator generator = KeyGenerator.getInstance(KEY_ALGORITHM1);
            generator.init(56);//56bit
            SecretKey secretKey = generator.generateKey();
            byte[] keyBytes = secretKey.getEncoded();//便于保存
            String keyStr = encoder.encode(keyBytes);
            System.out.println("秘钥 ： "+keyStr);
            // 2 : 加密
            String passwd = "123qwe";
            System.out.println("原文 : "+passwd);
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM1);
            cipher.init(Cipher.ENCRYPT_MODE , secretKey);
            byte[] enPasswd = cipher.doFinal(passwd.getBytes());

            String enPassStr = encoder.encode(enPasswd);
            System.out.println("密文 ： "+enPassStr);



            //乙方获取传输后的密码字节生成秘钥
            DESKeySpec dks = new DESKeySpec(keyBytes);
            SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_ALGORITHM1);
            SecretKey geKey = factory.generateSecret(dks);

            //解密
            Cipher cipher1 = Cipher.getInstance(KEY_ALGORITHM1);
            cipher1.init(Cipher.DECRYPT_MODE , geKey);
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] enbytes = decoder.decodeBuffer(enPassStr);
            byte[] decryptBytes = cipher1.doFinal(enbytes);
            String decryptStr = new String(decryptBytes);
            System.out.println("解密的明文 ： "+decryptStr);





        }catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

    //目前还没破解 ，秘钥默认长度128
    public static void AESTest() {
        try {
            BASE64Encoder encoder = new BASE64Encoder();

            // 1 : 生成秘钥
            KeyGenerator generator = KeyGenerator.getInstance(KEY_AES);
            generator.init(128);//128bit
            SecretKey secretKey = generator.generateKey();
            byte[] keyBytes = secretKey.getEncoded();//便于保存
            String keyStr = encoder.encode(keyBytes);
            System.out.println("秘钥 ： "+keyStr);
            // 2 : 加密
            String passwd = "123qwe";
            System.out.println("原文 : "+passwd);
            Cipher cipher = Cipher.getInstance(KEY_AES);
            cipher.init(Cipher.ENCRYPT_MODE , secretKey);
            byte[] enPasswd = cipher.doFinal(passwd.getBytes());

            String enPassStr = encoder.encode(enPasswd);
            System.out.println("密文 ： "+enPassStr);



            //乙方获取传输后的密码字节生成秘钥
            SecretKey geKey = new SecretKeySpec(keyBytes,KEY_AES);
//            DESKeySpec dks = new DESKeySpec(keyBytes);
//            SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_AES);
//            SecretKey geKey = factory.generateSecret(dks);

            //解密
            Cipher cipher1 = Cipher.getInstance(KEY_AES);
            cipher1.init(Cipher.DECRYPT_MODE , geKey);
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] enbytes = decoder.decodeBuffer(enPassStr);
            byte[] decryptBytes = cipher1.doFinal(enbytes);
            String decryptStr = new String(decryptBytes);
            System.out.println("解密的明文 ： "+decryptStr);

        }catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }


    public static void main(String[] args)  {
//        DesTest();
//        AESTest();
        TestRSA();
    }


    //RSA要求待加密数据不得大于53个字节 主要用于交换对称加密的秘钥 能用于加密和签名 基于因子分解难题
    private static final String KEY_ALGORITHM = "RSA";

    //非对称
    public static void TestRSA()  {
        //使用公钥 私钥都可以加密解密数据 但是用公钥加密无法辨别真伪
        BASE64Encoder encoder = new BASE64Encoder();
        BASE64Decoder decoder = new BASE64Decoder();

        try {
            KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            generator.initialize(512);
            KeyPair keyPair = generator.generateKeyPair();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            RSAPublicKey publickKey = (RSAPublicKey) keyPair.getPublic();
            String priKeyStr = encoder.encode(privateKey.getEncoded());
            String pubKeyStr = encoder.encode(publickKey.getEncoded());
            System.out.println("公钥 ： \n"+pubKeyStr);
            System.out.println("私钥 ： \n"+priKeyStr);

            String passwd = "123qwe";
            System.out.println("原文 ： "+passwd);

            byte[] pubkeyBytes = decoder.decodeBuffer(pubKeyStr);
//            byte[] pubkeyBytes = publickKey.getEncoded();
            // 1 公钥加密
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubkeyBytes);
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key pubKey = factory.generatePublic(keySpec);
            Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE , pubKey);
            byte[] encryptbytes = cipher.doFinal(passwd.getBytes());
            String encryStr = encoder.encode(encryptbytes);
            System.out.println("公钥加密密文 ：\n"+encryStr);

            //2 私钥解密
            cipher.init(Cipher.DECRYPT_MODE , privateKey);
            byte[] encryBytes = decoder.decodeBuffer(encryStr);
            byte[] decryptBytes = cipher.doFinal(encryBytes);
            String decryptStr = new String(decryptBytes);
            System.out.println("私钥解密密文 ：\n"+decryptStr);









        }catch (Exception e) {
            System.out.println(e.getMessage());
        }


    }



}
